'''
Description: 
Author: Zilu
Date: 2021-11-12 16:40:08
Version: 
LastEditTime: 2021-11-12 19:30:57
LastEditors: Zilu
'''

# XML比JSON复杂，但是还是有应用的地方
# DOM和SAX都可以操作XML，DOM把整个XML解析成树，占用内存大，解析慢，但是可以任意遍历树的节点
# SAX是流模式，占用内存小，解析快，缺点是要自己处理事件
# 正常情况下，优先考虑SAX，因为DOM实在太占内存

# 使用XML，通常只关心三个事件（以<a href="/">python</a> 节点为例）：
# start_element事件，在读取<a href="/">时；
# char_data事件，在读取python时；
# end_element事件，在读取</a>时。
from xml.parsers.expat import ParserCreate

class DefaultSaxHandler(object):
    def __init__(self) -> None:
        super().__init__()
        self.name = ''
        self.data = {}
    
    def start_elemet(self, name, attrs):
        self.name = name
        print('sax: start_element: %s, attrs: %s' % (name, str(attrs)))

    def end_elemet(self, name):
        print('sax: end_element: %s' % (name))

    def char_data(self, text):
        self.data[self.name] = text
        print('sax: char_data: %s' % (text))

xml = r'''<?xml version="1.0"?>
<ol>
    <li><a href="/python">Python</a></li>
    <li><a href="/ruby">Ruby</a></li>
</ol>
'''

handler = DefaultSaxHandler()
parser = ParserCreate()
parser.StartElementHandler = handler.start_elemet
parser.EndElementHandler = handler.end_elemet
parser.CharacterDataHandler = handler.char_data
parser.Parse()

# 生成简单结构的XML
L = []
L.append(r'<?xml version="1.0"?>')
L.append(r'<root>')
L.append('some & data'.encode('utf-8'))
L.append(r'</root>')
''.join(L)

# 复杂的XML还是使用JSON为好

# 练习：使用高德天气查询API获取实时天气，https://lbs.amap.com/api/webservice/guide/api/weatherinfo
def parseXml(xmlStr):
    print(xmlStr)

    handler = DefaultSaxHandler()
    parser = ParserCreate()
    # 创建的三个句柄对应
    parser.StartElementHandler = handler.start_elemet
    parser.EndElementHandler = handler.end_elemet
    parser.CharacterDataHandler = handler.char_data

    # 解析xmlStr信息
    parser.Parse(xmlStr)

    return handler.data

key = '1415357aaf9ef8f91b87ecd357831dea'
city = 430281
extensions = ['base', 'all']
output = ['JSON', 'XML']
URL = r'https://restapi.amap.com/v3/weather/weatherInfo?key=%s&city=%s&extensions=%s&output=%s' % (key, city, extensions[0], output[1])

from urllib import request
with request.urlopen(URL) as f:
    data = f.read().decode('utf-8')

result = parseXml(data)
print(result)


